/**
 *	Copyright (c) TeamFlamingo And gray 2004-2009
 *	www.me-live.com.cn / www.i-gray.cn
 *
 *	[ WARNING ]
 *		This is NOT a freeware!
 *		You MUST get author's authorization before using it!
 *	[ WARNING ]
 *
 *	Name : meHighlight.js / Development Code Evolve
 *	Created / Modify : 2008-10-29 / 2010-6-10
 */
var	meHighlight	=	Class({
	Version	:	'1.0.0',
	Author	:	'gray',
	Visit	:	'http://www.i-gray.cn',
	oNode	:	'textarea',

	IE		:	!!( window.attachEvent && !window.opera ),

	Block			:	false,			//	[CH]	多行模式
	BlockObj		:	false,			//	[CH]	多行模式对象

	init	:	function ( oNode, Container )
	{
		var	Container	=	Container ? Container : document;
		var	codeHighlight	=	$$( oNode, Container );

		this.oNode	=	oNode && oNode == 'pre' ? oNode : this.oNode;

		if( codeHighlight.length == 0 )
			return;

		if( !$( 'meHighlight' ) )
		{
			//alert( 'meHighlight 需要一个容器，但程序并没有找到' );
			return;
		}

		//MDK.imports( './app/templates/default/css/code.css' );

		//	[CH]	将文档中的代码存入临时数组
		var	Tempcode	=	[];
		for( var i = 0, j = codeHighlight.length; i < j; i++ )
		{
			if( codeHighlight[i].id == 'meSourceCode' )
			{
				Tempcode.push( codeHighlight[i] );
				codeHighlight[i].style.display	=	'none';
			}
		}

		if( Tempcode.length == 0 )
			return;

		for( var x in Tempcode )
		{
			this.createContainer( Tempcode[x], x );
			this.splitCodes( Tempcode[x] );
		}
	},

	splitCodes	:	function ( codes )
	{
		var	Tempcode	=	this.oNode == 'pre' ? codes.innerHTML : codes.value;
		//alert( codes );
		var	Tempcode	=	Tempcode.replace( /<br( \/>|>)/ig, '' );
		var	Tempcode	=	Tempcode.replace( /&/g, '&amp;' );
		var	Tempcode	=	Tempcode.replace( /</g, '&lt;' );
		var	Tempcode	=	Tempcode.replace( />/g, '&gt;' );
		var	Tempcode	=	Tempcode.replace( / /g, '&nbsp;' );
		var	Tempcode	=	Tempcode.replace( /\r\n|\n|\r/g, ' \n' );

		//	[CH]	根据换行符分割代码
		var	Templines	=	Tempcode.split( /\r\n|\n|\r/g );
		var	codeType	=	codes.className;

		//	[CH]	建立正则表达式
		var	regExp		=	( function ( object, codeType )
		{
			var	lib	=	object[codeType.toLowerCase()].libRegExp;
			var	Tempchar	=	[];

			for( var x in lib )
			{
				if( lib[x].endTags && lib[x].endTags != lib[x].startTags )
					Tempchar.push( lib[x].endTags );
				Tempchar.push( lib[x].startTags );
			}

			return	new RegExp( Tempchar.join( '|' ), 'ig' );
		} ) ( this, codeType );

		for( var x in Templines )
		{
			var	lis			=	document.createElement( 'li' );
			lis.innerHTML	=	this.getHighlight( Templines[x], codeType, regExp ).replace( /\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;' );
			$$( 'ol', codes.parentNode )[0].appendChild( lis );
		}

	},

	getHighlight	:	function ( codes, codeType, regExp )
	{
		if( MDK.String.trim( codes ) == '' || MDK.String.trim( codes ) == null )
			return	'&nbsp;';
		//alert( codes );

		var	getEndChar	=	function ( regexlib, pos )
		{
			//	[CH]	如果前一个字符是转义字符
			//	[CH]	那么直接返回
			if( codes.substr( pos - 1, 1 ) === '\\' )
				return	false;

			var	endTagsLength	=	regexlib.endTags.replace( /\\/g, '' ).length;
			var	tempcode		=	codes.substr( pos, endTagsLength );

			return	regexlib.endTags.replace( /\\/g, '' ) == tempcode ? pos + endTagsLength : false;
		}

		var	getStartChar	=	function ( regexlib, pos )
		{
			if( pos - 1 >= 0 && codes.substr( pos - 1, 1 ) === '\\' )
				return	false;

			for( var x in regexlib )
			{
				var	startTagsChar	=	regexlib[x].startTags.replace( /\\/g, '' );
				var	startTagsLength	=	startTagsChar.length;
				var	tempcode		=	codes.substr( pos, startTagsLength );

				if( startTagsChar == tempcode )
					return	regexlib[x]
				else
					continue;
			}

			return	false;
		}

		var	local		=	( function ( regExp )
		{
			var	Templocal	=	[codes.length];

			while( match = regExp.exec( codes ) )
				Templocal.push( match.index );

			return	Templocal.sort( function ( a, b ) { return a - b } );
		} ) ( regExp );

		var	Tempcode	=	[];
		var currentPos	=	0;	//	[CH]	当前指针
		var	codesLength	=	codes.length;
		var startTags	=	false;
		var	type		=	this[codeType.toLowerCase()].libRegExp;

		for( var x in local )
		{
			if( currentPos > local[x] )
				continue;

			if( !startTags && !this.Block )
			{
				var	libRegExp	=	getStartChar( type, local[x] );
				if( libRegExp )
				{
					//	[CH]	将未命中的代码高亮
					Tempcode.push( this.getKeywords( codes.slice( currentPos, local[x] ), this[codeType.toLowerCase()] ) );

					//	[CH]	如果不存在结束标签
					if( !libRegExp.endTags )
					{
						Tempcode.push( this.getColor( codes.substr( local[x] ), libRegExp['color'], libRegExp['bold'] ) );
						break;
					}

					//	[CH]	如果是多行模式
					if( libRegExp.multi )
					{
						this.Block	=	true;
						this.BlockObj	=	libRegExp;
					}

					//	[CH]	移动指针
					currentPos	=	local[x];
					//	[CH]	定义起始标签为真
					startTags	=	true;
				}
				else if( local[x] == codesLength )
				{
					//	[CH]	将未命中的代码高亮
					Tempcode.push( this.getKeywords( codes.slice( currentPos, local[x] ), this[codeType.toLowerCase()] ) );
					break;
				}
				//continue;
			}
			else
			{
				/*if( currentPos >= local[x] )
					continue;*/

				var	libRegExp	=	this.BlockObj ? this.BlockObj : libRegExp;
				var	endTagsPos	=	/*local[x] == codesLength ? codesLength : */getEndChar( libRegExp, local[x] );
				//alert( endTagsPos );

				if( /*this.Block && */local[x] == codesLength )
				//if( this.Block && !getEndChar( libRegExp, local[x] ) )
				{
					Tempcode.push( this.getColor( codes.slice( currentPos, codesLength ), libRegExp['color'], libRegExp['bold'] ) );
					break;
				}
				else if( endTagsPos )/* //if( this.Block && getEndChar( libRegExp, local[x] ) )*/
				{
					//alert( '(etags)' + currentPos );
					Tempcode.push( this.getColor( codes.slice( currentPos, endTagsPos ), libRegExp['color'], libRegExp['bold'] ) );
					currentPos	=	endTagsPos;
					startTags	=	false;

					this.Block	=	false;
					this.BlockObj	=	false;
				}
				//continue;
			}
		}

		return	Tempcode.join( '' );
	},

	keywordRegExp	:	function ( str )
	{
		return '\\b' + str.replace( / /g, '\\b|\\b' ) + '\\b';
	},

	getKeywords		:	function ( value, regExplib )
	{
		var	$M	=	this;
		var	keywordslib		=	regExplib.keywords;
		for( var i in keywordslib )
		{
			var	regExp	=	new	RegExp( this.keywordRegExp( keywordslib[i].group ), 'ig' );
			var	value	=	value.replace( regExp, function($1){ return $M./*meHighlight.*/getColor( $1, keywordslib[i]['color'], keywordslib[i]['bold'] ) } );
		}
		return	value;
	},

	getColor		:	function ( value/* 关键字 */, color/* 关键字颜色 */, fontWeight/* 粗体 */ )
	{
		var	fontWeight	=	fontWeight ? '600' : '400';
		return	'<span style="color: ' + color + ';font-weight: ' + fontWeight + '">' + value + '</span>';
	},

	//	[CH]	创建容器
	createContainer	:	function ( obj, id )
	{
		var	m	=	this;
		var	codeInfo	=	document.createElement( 'div' );
		var	ols			=	document.createElement( 'ol' );

		codeInfo.id		=	'meHighlightInfo';
		codeInfo.innerHTML	=	'<span>' + obj.className + '代码</span>' + '&nbsp;[ <a id="CopyToClipboard-' + id + '">复制到剪切板</a> ]' + '&nbsp;<a href="' + m.Visit + '">Highlight<sup>' + m.Version + '</sup> The JavaScript Project By gray</a>';

		obj.parentNode.appendChild( codeInfo );
		obj.parentNode.appendChild( ols );

		var	a			=	$( 'CopyToClipboard-' + id )
		a.onclick		=	function (e) { m.CopyToClipboard( obj.value ) };
		a.onmouseover	=	function (e) { this.style.color = '#f00' };
		a.onmouseout	=	function (e) { this.style.color = '' };
	},

	CopyToClipboard	:	function ( code )
	{
		if( this.IE && window.clipboardData.setData( 'text', code ) )
			alert( '代码已经复制到剪切板' );
		else
			alert( '浏览器功能限制：无法完成所选动作' );
	}
});

meHighlight.prototype.javascript	=
{
	keywords	:
	[
		//	[CH]	Js保留字
		{
			group : 'break delete function return typeof case do if switch var catch else in this void continue false instanceof throw while debugger finally new true with default for null try',
			color : '#00f',
			bold : true
		},

		//	[CH]	Js方法
		{
			group : 'abs acos anchor asin atan atan2 atEnd big blink bold ceil charAt charCodeAt compile concat cos dimensions escape eval exec exp fixed floor fontcolor fontsize fromCharCode getDate getDay getFullYear getHours getItem getMilliseconds getMinutes getMonth getSeconds getTime getTimezoneOffset getUTCDate getUTCDay getUTCFullYear getUTCHours getUTCMilliseconds getUTCMinutes getUTCMonth getUTCSeconds getVarDate getYear indexOf isFinite isNaN italics item join lastIndexOf lbound link log match max min moveFirst moveNext parse parseFloat parseInt pow random replace reverse round search setDate setFullYear setHours setMilliseconds setMinutes setMonth setSeconds setTime setUTCDate setUTCFullYear setUTCHours setUTCMilliseconds setUTCMinutes setUTCMonth setUTCSeconds setYear sin slice small sort split sqrt strike sub substr substring sup tan test toArray toGMTString toLocaleString toLowerCase toString toUpperCase toUTCString ubound unescape UTC valueOf',
			color : '#909',
			bold : false
		},

		{
			group : 'add addBehavior AddChannel AddDesktopComponent AddFavorite addImport addPageRule addReadRequest addRule alert appendChild appendData applyElement assign attachEvent AutoCompleteSaveForm AutoScan back blur ChooseColorDlg clear clearAttributes clearData clearInterval clearRequest clearTimeout click cloneNode close collapse compareEndPoints componentFromPoint confirm contains createAttribute createCaption createComment createControlRange createDocumentFragment createElement createEventObject createPopup createRangecontrolRange createRangeCollection createStyleSheet createTextNode createTextRange createTFoot createTHead deleteCaption deleteCell deleteData deleteRow deleteTFoot deleteTHead detachEvent doImport doReadRequest doScroll dragDrop duplicate elementFromPoint empty execCommand execScript expand findText fireEvent firstPage focus forward getAdjacentText getAttribute getAttributeNode getBookmark getBoundingClientRect getClientRects getData getElementById getElementsByName getElementsByTagName getExpression getNamedItem go hasChildNodes hasFeature hasFocus hide ImportExportFavorites inRange insertAdjacentElement insertAdjacentHTML insertAdjacentText insertBefore insertCell insertData insertRow isEqual IsSubscribed item javaEnabled lastPage mergeAttributes move moveBy moveEnd moveRow moveStart moveTo moveToBookmark moveToElementText moveToPoint namedItem namedRecordset navigate NavigateAndFind nextPage normalize open parentElement pasteHTML previousPage print prompt queryCommandEnabled queryCommandIndeterm queryCommandState queryCommandSupported queryCommandValue recalc refresh releaseCapture reload remove removeAttribute removeAttributeNode removeBehavior removeChild removeExpression removeNamedItem removeNode removeRule replace replaceAdjacentText replaceChild replaceData replaceNode reset resizeBy resizeTo scroll scrollBy scrollIntoView scrollTo select setActive setAttribute setAttributeNode setCapture setData setEndPoint setExpression setInterval setNamedItem setTimeout show ShowBrowserUI showHelp showModalDialog showModelessDialog splitText start stop submit substringData swapNode tags taintEnabled urns write writeln',
			color : '#909',
			bold : false
		},

		{
			group : 'onabort onactivate onafterprint onafterupdate onbeforeactivate onbeforecopy onbeforecut onbeforedeactivate onbeforeeditfocus onbeforepaste onbeforeprint onbeforeunload onbeforeupdate onblur onbounce oncellchange onchange onclick oncontextmenu oncontrolselect oncopy oncut ondataavailable ondatasetchanged ondatasetcomplete ondblclick ondeactivate ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop onerror onerrorupdate onfilterchange onfinish onfocus onfocusin onfocusout onhelp onkeydown onkeypress onkeyup onlayoutcomplete onload onlosecapture onmousedown onmouseenter onmouseleave onmousemove onmouseout onmouseover onmouseup onmousewheel onmove onmoveend onmovestart onpaste onpropertychange onreadystatechange onreset onresize onresizeend onresizestart onrowenter onrowexit onrowsdelete onrowsinserted onscroll onselect onselectionchange onselectstart onstart onstop onsubmit onunload',
			color : '#f00',
			bold : false
		}
	],

	libRegExp	:
	[
		{ startTags	: '//', endTags	: false, multi : false, color : '#080' },
		{ startTags	: '/\\*', endTags	: '\\*/', multi : true, color : '#888' },
		{ startTags	: "'", endTags	: "'", multi : false, color : '#f06' },
		{ startTags	: '"', endTags	: '"', multi : false, color : '#f0f' },
	]
}